﻿Imports Newtonsoft.Json.Linq
Imports System.Globalization

Namespace Core

    ''' <summary>
    ''' Core functionality - Connects an reads the WBSAPI
    ''' </summary>
    ''' <remarks></remarks>
    Friend NotInheritable Class WBSAPIConnector


        Private m_withingsServiceBaseAddress As String = "http://wbsapi.withings.net/"
        Private Shared m_webConnector As IHttpConnector = Nothing

        ''' <summary>
        ''' Gets or Sets the engine for downloading a website
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared Property WebConnector() As IHttpConnector
            Get
                Return m_webConnector
            End Get
            Set(ByVal value As IHttpConnector)
                m_webConnector = value
            End Set
        End Property
        ''' <summary>
        ''' Gets or sets the base website address for the Withings Body metric Services API - don't change if it is not necessary
        ''' </summary>
        ''' <value>DefaultValue = http://wbsapi.withings.net/</value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property WSBAPIAddress() As String
            Get
                Return m_withingsServiceBaseAddress
            End Get
            Set(ByVal value As String)
                m_withingsServiceBaseAddress = value
            End Set
        End Property


        ''' <summary>
        ''' Creates a queryable websiteaddress
        ''' </summary>
        ''' <param name="serviceName"></param>
        ''' <param name="action"></param>
        ''' <param name="parameter">(Optional) List of parameters</param>
        ''' <exception cref="System.ArgumentNullException">thrown, if serviceName or action is null or empty</exception>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Function BuildWSBAPIAddress(ByVal serviceName As String, ByVal action As String, Optional ByVal parameter As Generic.Dictionary(Of String, String) = Nothing) As String
            If String.IsNullOrEmpty(serviceName) Then _
                Throw New ArgumentNullException("serviceName")

            If String.IsNullOrEmpty(action) Then _
                Throw New ArgumentNullException("action")

            Dim retVal As System.Text.StringBuilder

            retVal = New System.Text.StringBuilder
            retVal.Append(m_withingsServiceBaseAddress)

            If Not m_withingsServiceBaseAddress.EndsWith("/", StringComparison.OrdinalIgnoreCase) Then
                retVal.Append("/")
            End If

            retVal.Append(serviceName)
            retVal.Append("?")
            retVal.Append("action=")
            retVal.Append(action)

            If parameter IsNot Nothing AndAlso parameter.Count > 0 Then
                For Each de As KeyValuePair(Of String, String) In parameter
                    retVal.Append("&" + de.Key + "=" + de.Value)
                Next
            End If

            Return retVal.ToString
        End Function

        ''' <summary>
        ''' To compute the hash value, it is nessecary to get the magic string
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function GetMagicStringForHash() As String
            Dim address As String
            Dim retVal As String
            Dim result As String
            Dim jObj As JObject

            address = BuildWSBAPIAddress("once", "get")

            result = m_webConnector.GetWebserviceResponse(address)

            ReadStatus(result)

            jObj = JObject.Parse(result)
            retVal = CType(jObj.SelectToken("body.once"), JValue).Value.ToString

            Return retVal
        End Function
        ''' <summary>
        ''' Returns true, if the Service is accessible
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function CheckWebserviceConnection() As Boolean
            Dim retVal As Boolean
            Dim address As String
            address = BuildWSBAPIAddress("once", "probe")
            Dim result As String
            result = m_webConnector.GetWebserviceResponse(address)

            retVal = (result = "{""status"":0}")

            Return retVal
        End Function

        ''' <summary>
        ''' Gets the specfied User
        ''' </summary>
        ''' <param name="userID"></param>
        ''' <param name="publicKey"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function GetUser(ByVal userID As Integer, ByVal publicKey As String) As GetUserByIDResponse
            Dim address As String
            Dim params As New Generic.Dictionary(Of String, String)
            Dim retVal As GetUserByIDResponse
            Dim userList As New Generic.List(Of User)
            Dim jObj As JObject
            If userID <= 0 Then _
                Throw New ArgumentNullException("userID")

            If String.IsNullOrEmpty(publicKey) Then _
                Throw New ArgumentNullException("publicKey")


            params.Add("userid", CStr(userID))
            params.Add("publickey", publicKey)

            address = BuildWSBAPIAddress("user", "getbyuserid", params)

            Dim result As String
            Dim status As New StatusResponseEnum
            result = m_webConnector.GetWebserviceResponse(address)

            status = ReadStatus(result)

            If status = StatusResponseEnum.Successfull Then

                jObj = JObject.Parse(result)

                For i As Integer = 0 To CType(jObj.SelectToken("body.users"), JArray).Count - 1
                    Dim tmpList As New Generic.Dictionary(Of String, String)
                    Dim obj As JObject = CType(CType(jObj.SelectToken("body.users"), JArray).Item(i), JObject)

                    tmpList.Add("publickey", publicKey)
                    For Each userProperty As JProperty In obj.Properties

                        tmpList.Add(userProperty.Name, userProperty.Value.ToString)

                    Next
                    userList.Add(CreateNewWithingsUser(tmpList))
                Next

                retVal = New GetUserByIDResponse(status, userList.First)

            Else
                retVal = New GetUserByIDResponse(status, Nothing)
            End If

            Return retVal
        End Function
        ''' <summary>
        ''' Updates an User Account. Important: Public Key Changes after that
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function UpdateUser(ByVal userID As Integer, ByVal publicKey As String, ByVal isPublic As Integer) As UpdateUserResponse
            Dim retVal As UpdateUserResponse

            Dim address As String
            Dim params As New Generic.Dictionary(Of String, String)

            If userID <= 0 Then _
                Throw New ArgumentNullException("userID")

            If String.IsNullOrEmpty(publicKey) Then _
                Throw New ArgumentNullException("publicKey")

            If isPublic < 0 Then _
                Throw New ArgumentNullException("isPublic")


            params.Add("userid", CStr(userID))
            params.Add("publickey", publicKey)
            params.Add("ispublic", CStr(isPublic))

            address = BuildWSBAPIAddress("user", "update", params)

            Dim result As String
            Dim status As Core.StatusResponseEnum
            result = m_webConnector.GetWebserviceResponse(address)

            status = ReadStatus(result)

            retVal = New UpdateUserResponse(status)

            Return retVal
        End Function

        ''' <summary>
        ''' Returns the Userlist for an Account. Please don't call this directly - use the WithingsAccount calls instead. THis class knowns to create the hash Value
        ''' </summary>
        ''' <param name="emailAddress"></param>
        ''' <param name="hash"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function GetAccountUsers(ByVal emailAddress As String, ByVal hash As String) As GetUserListResponse
            Dim address As String
            Dim params As New Generic.Dictionary(Of String, String)
            Dim userList As New Generic.List(Of User)
            Dim retval As GetUserListResponse
            Dim jObj As JObject

            If String.IsNullOrEmpty(emailAddress) Then _
                Throw New ArgumentNullException("emailAddress")

            If String.IsNullOrEmpty(hash) Then _
                Throw New ArgumentNullException("hash")


            params.Add("email", emailAddress)
            params.Add("hash", hash)

            address = BuildWSBAPIAddress("account", "getuserslist", params)

            Dim result As String
            Dim status As Core.StatusResponseEnum
            result = m_webConnector.GetWebserviceResponse(address)

            status = ReadStatus(result)
            If status = StatusResponseEnum.Successfull Then

                jObj = JObject.Parse(result)

                For i As Integer = 0 To CType(jObj.SelectToken("body.users"), JArray).Count - 1
                    Dim tmpList As New Generic.Dictionary(Of String, String)
                    Dim obj As JObject = CType(CType(jObj.SelectToken("body.users"), JArray).Item(i), JObject)

                    For Each userProperty As JProperty In obj.Properties

                        tmpList.Add(userProperty.Name, userProperty.Value.ToString)

                    Next
                    userList.Add(CreateNewWithingsUser(tmpList))
                Next

            End If

            retval = New GetUserListResponse(status, userList.ToArray)

            Return retval
        End Function

        ''' <summary>
        ''' Transferss the WBSAPI JSON Properties into my withingsUser-Obeject
        ''' </summary>
        ''' <param name="parameterList"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Shared Function CreateNewWithingsUser(ByVal parameterList As Generic.Dictionary(Of String, String)) As User

            Dim userID As Integer
            Dim pulicKey As String = String.Empty

            Dim firstName As String = String.Empty
            Dim lastName As String = String.Empty
            Dim shortName As String = String.Empty
            Dim gender As GenderEnum = GenderEnum.Female
            Dim fatMethod As String = String.Empty
            Dim birthdate As DateTime
            Dim isBodyScaleDataPublic As Boolean
            Dim isBloodPressureMonitorDataPublic As Boolean



            For Each de As Generic.KeyValuePair(Of String, String) In parameterList
                Select Case de.Key
                    Case "id"
                        userID = CInt(de.Value)
                    Case "firstname"
                        firstName = de.Value.Replace("""", "")
                    Case "lastname"
                        lastName = de.Value.Replace("""", "")
                    Case "shortname"
                        shortName = de.Value.Replace("""", "")
                    Case "gender"
                        gender = CType(CInt(de.Value), GenderEnum)
                    Case "fatmethod"
                        fatMethod = de.Value.Replace("""", "")
                    Case "birthdate"
                        Dim starttime As DateTime = New DateTime(1970, 1, 1, 0, 0, 0)
                        birthdate = starttime.AddSeconds(CLng(de.Value))
                    Case "ispublic"
                        Select Case CInt(de.Value)
                            Case 0
                                isBodyScaleDataPublic = False
                                isBloodPressureMonitorDataPublic = False
                            Case 1
                                isBodyScaleDataPublic = True
                                isBloodPressureMonitorDataPublic = False
                            Case 4
                                isBodyScaleDataPublic = False
                                isBloodPressureMonitorDataPublic = True
                            Case 5
                                isBodyScaleDataPublic = True
                                isBloodPressureMonitorDataPublic = True
                        End Select
                    Case "publickey"
                        pulicKey = de.Value.Replace("""", "")
                End Select
            Next

            Return New User(userID, pulicKey, firstName, lastName, shortName, gender, fatMethod, birthdate, isBodyScaleDataPublic, isBloodPressureMonitorDataPublic)
        End Function

        ''' <summary>
        ''' Gets a users measures
        ''' </summary>
        ''' <param name="userID">The userid of the target user. This can be obtained through an account/getuserslist or through the user's "Share" overlay in the dashboard.</param>
        ''' <param name="publicKey">The public key associated with the userid. This can be obtained through an account/getuserslist or through the user's "Share" overlay in the dashboard.</param>
        ''' <param name="startDate">Will prevent retrieval of values dated prior to the supplied parameter.</param>
        ''' <param name="endDate">Will prevent retrieval of values dated after the supplied parameter.</param>
        ''' <param name="devtype">Will retrieve data for this particular device type.</param>
        ''' <param name="meastype">Will restrict the type of data retrieved (see below the type list). Please note that currently this filter only supports weight (ie type 1) height (ie type 4) types.</param>
        ''' <param name="lastUpdate">Is useful for performing data synchronization. </param>
        ''' <param name="category">Can be set to 2 to retrieve objectives or to 1 to retrieve actual measurements.</param>
        ''' <param name="limit">Can be used to limit the number of measure groups returned in the result.</param>
        ''' <param name="offset">Can be used to skip the 'offset' most recent measure group records of the result set.</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function GetMeasures(ByVal userID As Integer, ByVal publicKey As String, _
                                    Optional ByVal startDate As Integer = -1, _
                                    Optional ByVal endDate As Integer = -1, _
                                    Optional ByVal devtype As Integer = -1, _
                                    Optional ByVal meastype As Integer = -1, _
                                    Optional ByVal lastUpdate As Integer = -1, _
                                    Optional ByVal category As Integer = -1, _
                                    Optional ByVal limit As Integer = -1, _
                                    Optional ByVal offset As Integer = -1) As GetMeasuresResponse

            If userID <= 0 Then _
                Throw New ArgumentNullException("userID")

            If String.IsNullOrEmpty(publicKey) Then _
                Throw New ArgumentNullException("publicKey")

            Dim address As String = String.Empty
            Dim params As New Generic.Dictionary(Of String, String)
            Dim retVal As GetMeasuresResponse
            Dim jObj As JObject = Nothing


            params.Add("userid", CStr(userID))
            params.Add("publickey", publicKey)



            If startDate > -1 Then params.Add("startdate", CStr(startDate))
            If endDate > -1 Then params.Add("enddate", CStr(endDate))
            If devtype > -1 Then params.Add("devtype", CStr(devtype))
            If meastype > -1 Then params.Add("meastype", CStr(meastype))
            If lastUpdate > -1 Then params.Add("lastupdate", CStr(lastUpdate))
            If category > -1 Then params.Add("category", CStr(category))

            If limit > -1 Then params.Add("limit", CStr(limit))
            If offset > -1 Then params.Add("offset", CStr(startDate))

            address = BuildWSBAPIAddress("measure", "getmeas", params)

            Dim wbsapiResponse As String
            Dim status As StatusResponseEnum
            wbsapiResponse = m_webConnector.GetWebserviceResponse(address)

            status = ReadStatus(wbsapiResponse)

            If status = StatusResponseEnum.Successfull Then


                jObj = JObject.Parse(wbsapiResponse)

                Dim val As Integer = CInt(CType(jObj.SelectToken("body.updatetime"), JValue).Value)
                Dim updateTime As DateTime = New DateTime(1970, 1, 1).AddSeconds(val)
                Dim hasMore As Boolean = False

                If Not jObj.SelectToken("body.more") Is Nothing Then
                    hasMore = CBool(CType(jObj.SelectToken("body.more"), JValue).Value)
                End If

                retVal = New GetMeasuresResponse(status, updateTime, hasMore)

                For i As Integer = 0 To CType(jObj.SelectToken("body.measuregrps"), JArray).Count - 1
                    'Hier Measure groups befüllen
                    retVal.AddMeasureGroup(CreateMeasureGroup(CType(CType(jObj.SelectToken("body.measuregrps"), JArray).Item(i), JObject)))

                Next
            Else
                retVal = New GetMeasuresResponse(status, DateTime.Now, False)
            End If



            Return retVal
        End Function


        ''' <summary>
        ''' This service allows third parties to subscribe to notifications. Once the notification service has been subscribed, the WBS API will notify the subscriber whenever the target user's measurements or objectives are added, modified or deleted.
        ''' This allows third party applications to remain in sync with user's data.
        ''' To monitor a user, its userid and publickey are needed. Please note that unless the subscribed users have made their measurements data public, no notifications will be sent (see user/update on how to enable it).
        ''' </summary>
        ''' <param name="userID">The userid of the target user.</param>
        ''' <param name="publicKey">The public key associated with the userid.</param>
        ''' <param name="callbackURL">The URL-encoded URL used when subscribing to the notification service for the specified user.</param>
        ''' <param name="application">Default value : 1 (Bodyscale). This field specifies the device type for which the notification is to be retrieved. See measure/getmeas for supported device types.</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function CreateSubscribtion(ByVal userID As Integer, ByVal publicKey As String, ByVal callbackURL As String, ByVal comment As String, Optional ByVal application As DeviceTypeEnum = DeviceTypeEnum.BodyScale) As SetSubscriptionResponse
            If userID <= 0 Then _
                Throw New ArgumentNullException("userID")

            If String.IsNullOrEmpty(publicKey) Then _
                Throw New ArgumentNullException("publicKey")

            If String.IsNullOrEmpty(callbackURL) Then _
                Throw New ArgumentNullException("callbackURL")

            If callbackURL.Length > 128 Then _
                Throw New ArgumentException("callbackURL should not be longer than 128 chars", "callbackURL")

            If String.IsNullOrEmpty(comment) Then _
                Throw New ArgumentNullException("comment")


            Dim address As String = String.Empty
            Dim params As New Generic.Dictionary(Of String, String)
            Dim wbsapiResponse As String
            Dim retVal As SetSubscriptionResponse


            params.Add("userid", CStr(userID))
            params.Add("publickey", publicKey)
            params.Add("callbackurl", Helper.UrlEncode(callbackURL))
            params.Add("appli", CStr(CInt(application)))
            params.Add("comment", Helper.EscapeUriString(comment))

            address = BuildWSBAPIAddress("notify", "subscribe", params)

            Dim status As StatusResponseEnum
            wbsapiResponse = m_webConnector.GetWebserviceResponse(address)
            status = ReadStatus(wbsapiResponse)

            retVal = New SetSubscriptionResponse(status)

            Return retVal
        End Function
        ''' <summary>
        ''' This service allows third party applications to check whether the notification service was previously subscribed on a specific user and to retrieve the subscription expiry date.
        ''' </summary>
        ''' <param name="userID">The userid of the target user.</param>
        ''' <param name="publicKey">The public key associated with the userid.</param>
        ''' <param name="callbackURL">The URL-encoded URL used when subscribing to the notification service for the specified user.</param>
        ''' <param name="application">Default value : 1 (Bodyscale). This field specifies the device type for which the notification is to be retrieved. See measure/getmeas for supported device types.</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function ReadSubscription(ByVal userID As Integer, ByVal publicKey As String, ByVal callbackURL As String, Optional ByVal application As DeviceTypeEnum = DeviceTypeEnum.BodyScale) As ReadSubscriptionResponse
            If userID <= 0 Then _
                Throw New ArgumentNullException("userID")

            If String.IsNullOrEmpty(publicKey) Then _
                Throw New ArgumentNullException("publicKey")

            If String.IsNullOrEmpty(callbackURL) Then _
                Throw New ArgumentNullException("callbackURL")

            If callbackURL.Length > 128 Then _
                Throw New ArgumentException("callbackURL should not be longer than 128 chars", "callbackURL")


            Dim address As String = String.Empty
            Dim params As New Generic.Dictionary(Of String, String)
            Dim wbsapiResponse As String
            Dim retVal As ReadSubscriptionResponse = Nothing
            Dim jObj As JObject = Nothing

            params.Add("userid", CStr(userID))
            params.Add("publickey", publicKey)
            params.Add("callbackurl", Web.HttpUtility.UrlEncode(callbackURL))
            params.Add("appli", CStr(CInt(application)))

            address = BuildWSBAPIAddress("notify", "get", params)


            Dim status As StatusResponseEnum
            Dim expireEpoch As Integer = 0
            Dim comment As String = Nothing

            wbsapiResponse = m_webConnector.GetWebserviceResponse(address)
            status = ReadStatus(wbsapiResponse)

            If status = StatusResponseEnum.Successfull Then
                jObj = JObject.Parse(wbsapiResponse)

                expireEpoch = CInt(CType(jObj.SelectToken("body.expires"), JValue).Value)
                comment = CType(jObj.SelectToken("body.comment"), JValue).Value.ToString
            End If

            retVal = New ReadSubscriptionResponse(status, _
                                                  Helper.EPOCHToDateTime(expireEpoch), _
                                                  comment)
            Return retVal
        End Function
        ''' <summary>
        ''' This service allows third party applications to revoke a previously subscribed notification. This will disable the push feature between the WBS API and the specified applications for the specified user.
        ''' </summary>
        ''' <param name="userID">The userid of the target user.</param>
        ''' <param name="publicKey">The public key associated with the userid.</param>
        ''' <param name="callbackURL">The URL-encoded URL used when subscribing to the notification service for the specified user.</param>
        ''' <param name="application">Default value : 1 (Bodyscale). This field specifies the device type for which the notification is to be retrieved. See measure/getmeas for supported device types.</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function RevokeSubscription(ByVal userID As Integer, _
                                           ByVal publicKey As String, _
                                           ByVal callbackURL As String, _
                                           Optional ByVal application As DeviceTypeEnum = DeviceTypeEnum.BodyScale) _
                                           As SetSubscriptionResponse

            If userID <= 0 Then _
                Throw New ArgumentNullException("userID")

            If String.IsNullOrEmpty(publicKey) Then _
                Throw New ArgumentNullException("publicKey")

            If String.IsNullOrEmpty(callbackURL) Then _
                Throw New ArgumentNullException("callbackURL")

            If callbackURL.Length > 128 Then _
                Throw New ArgumentException("callbackURL should not be longer than 128 chars", "callbackURL")

            Dim address As String = String.Empty
            Dim params As New Generic.Dictionary(Of String, String)
            Dim wbsapiResponse As String
            Dim retVal As SetSubscriptionResponse

            params.Add("userid", CStr(userID))
            params.Add("publickey", publicKey)
            params.Add("callbackurl", Web.HttpUtility.UrlEncode(callbackURL))
            params.Add("appli", CStr(CInt(application)))

            address = BuildWSBAPIAddress("notify", "revoke", params)

            wbsapiResponse = m_webConnector.GetWebserviceResponse(address)

            Dim status As StatusResponseEnum
            status = ReadStatus(wbsapiResponse)

            retVal = New SetSubscriptionResponse(status)

            Return retVal

        End Function


        Private Shared Function CreateMeasureGroup(ByVal measGrp As JObject) As MeasureGroup
            Dim retVal As New MeasureGroup
            For Each mesaGrpProperty As JProperty In measGrp.Properties

                If TypeOf (mesaGrpProperty.Value) Is JValue Then
                    Select Case mesaGrpProperty.Name
                        Case "grpid"
                            retVal.GroupId = CInt(mesaGrpProperty.Value)
                        Case "attrib"
                            retVal.AttributionStatus = CType(CInt(mesaGrpProperty.Value), AttributionStatusEnum)
                        Case "date"
                            retVal.MeasureGroupDate = Helper.EPOCHToDateTime(CInt(mesaGrpProperty.Value))
                        Case "category"
                            retVal.Category = CType(CInt(mesaGrpProperty.Value), CategoryEnum)
                    End Select
                ElseIf mesaGrpProperty.Name = "measures" Then

                    'Durch iterieren oder einfach string nehmen
                    For Each obj As JObject In CType(mesaGrpProperty.Value, JArray)
                        Dim measType As MeasureTypeEnum
                        Dim measValue As Integer
                        Dim measUnit As Integer
                        For Each prop As JProperty In obj.Properties

                            Select Case prop.Name
                                Case "value"
                                    measValue = CInt(prop.Value)
                                Case "type"
                                    measType = CType(CInt(prop.Value), MeasureTypeEnum)
                                Case "unit"
                                    measUnit = CInt(prop.Value)
                            End Select

                        Next

                        retVal.AddMeasure(New Measure(measValue, measUnit, measType))
                    Next

                End If

            Next
            Return retVal
        End Function
        Private Shared Function ReadStatus(ByVal response As String) As StatusResponseEnum
            Dim status As JValue
            Dim statusCode As Long

            status = CType(JObject.Parse(response).SelectToken("status"), JValue)
            statusCode = Long.Parse(status.Value.ToString, CultureInfo.CurrentCulture)

            Return CType(statusCode, StatusResponseEnum)

        End Function


        'Private Function GetErrorTextForStatus(ByVal statusCode As Integer) As String
        '    Dim errorMessage As String
        '    Select Case statusCode
        '        Case 100
        '            errorMessage = My.Resources.WBSAPI_Error_100_Message
        '        Case 247
        '            errorMessage = My.Resources.WBSAPI_Error_247_Message
        '        Case 250
        '            errorMessage = My.Resources.WBSAPI_Error_250_Message
        '        Case 264
        '            errorMessage = My.Resources.WBSAPI_Error_264_Message
        '        Case 286
        '            errorMessage = My.Resources.WBSAPI_Error_286_Message
        '        Case 293
        '            errorMessage = My.Resources.WBSAPI_Error_293_Message
        '        Case 294
        '            errorMessage = My.Resources.WBSAPI_Error_294_Message
        '        Case 304
        '            errorMessage = My.Resources.WBSAPI_Error_304_Message
        '        Case 2555
        '            errorMessage = My.Resources.WBSAPI_Error_2555_Message
        '        Case Else
        '            errorMessage = "Unkown exception code"
        '    End Select
        '    Return errorMessage
        'End Function
        ''' <summary>
        ''' Creates a new WBSAPI Connector an initiates a new httpConnector
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub New()
            If m_webConnector Is Nothing Then m_webConnector = New HttpConnector
        End Sub

    End Class

End Namespace